from tortoise.expressions import Q
from tortoise.transactions import in_transaction

from app.controllers.saas.buckling import buckling_controller
from app.controllers.saas.buckling_detail import buckling_detail_controller
from app.core.crud import CRUDBase
from app.models import BucklingDetail
from app.models.saas import Cases, Buckling
from app.schemas.saas import CasesCreate, CasesUpdate, BucklingDetailCreate
from app.log.log import logger

class TransactionError(Exception):
    """自定义异常类，用于事务失败时回滚"""
    pass


class CasesController(CRUDBase[Cases, CasesCreate, CasesUpdate]):
    def __init__(self):
        super().__init__(model=Cases)

    async def do_list(self, page: int, page_size: int, search: Q = Q()):
        query = self.model.filter(search)
        total = await query.count()
        objs =  await query.offset((page - 1) * page_size).limit(page_size).order_by('-id')
        data = [await obj.to_dict(exclude_fields=["updated_at","deleted_at"]) for obj in objs]
        return total, data

    async def do_detail(self,data_id:int):
        obj = await self.get(id=data_id)
        data = await obj.to_dict()
        return data

    async def do_create(self, obj_in: CasesCreate):
        try:
            async with in_transaction() as transaction:
                ret = await self.create(obj_in=obj_in)
                buckling_data = obj_in.buckling_data
                for item in buckling_data:
                    ##批量插入划扣记录
                    buckling_id = item["buckling_id"]
                    nums = item["nums"]
                    buckling = await Buckling.get(id=buckling_id)
                    buckling_dict = await buckling.to_dict()
                    if nums>0:
                        date_detail = BucklingDetailCreate(
                            buckling_id=buckling_id,
                            nums=nums,
                            cases_id=ret.id,
                            buckling_price=buckling_dict['price']/nums
                        )
                        await buckling_detail_controller.do_create(obj_in=date_detail)
                    ##更新buckling的使用记录和剩余数量
                    buckling_data = await Buckling.filter(id=buckling_id).first().values("use_nums","last_nums")
                    use_nums = buckling_data["use_nums"]
                    last_nums = buckling_data["last_nums"]
                    new_use_nums = use_nums + nums
                    new_last_nums = last_nums - nums
                    if new_last_nums<0:
                        # 手动抛出异常来触发回滚
                        logger.info(f"不足划扣请检查,划扣编号: {buckling_id}")
                        raise TransactionError(f"不足划扣请检查,划扣编号: {buckling_id}")
                    await Buckling.filter(id=buckling_id).update(use_nums=new_use_nums,last_nums=new_last_nums)
            return True
        except TransactionError:
            # 捕获自定义异常并返回 False
            return False  # 事务回滚后返回 False

        except Exception as e:
            # 其他异常捕获，确保所有错误都会返回 False
            return False

    async def do_update(self, obj_in: CasesUpdate):
        await self.update(id=obj_in.id, obj_in=obj_in)
        return True

    async def do_delete(self, data_id: int):
        async with in_transaction() as transaction:
            await self.remove(id=data_id)
            details = await BucklingDetail.filter(cases_id=data_id).all().values()
            for item in details:
                ##每一条都给他恢复
                buckling_data = await Buckling.filter(id=item["buckling_id"]).first().values("use_nums", "last_nums")
                use_nums = buckling_data["use_nums"]
                last_nums = buckling_data["last_nums"]
                new_use_nums = use_nums - item["nums"]
                new_last_nums = last_nums + item["nums"]
                await Buckling.filter(id=item["buckling_id"]).update(use_nums=new_use_nums, last_nums=new_last_nums)
                await buckling_detail_controller.do_delete(data_id=item["id"])
        return True




cases_controller = CasesController()
